Index: portal-impl/src/com/liferay/portal/events/ExtensionPointUtil.java =================================================================== --- portal-impl/src/com/liferay/portal/events/ExtensionPointUtil.java (revision 0) +++ portal-impl/src/com/liferay/portal/events/ExtensionPointUtil.java (revision 0) @@ -0,0 +1,137 @@ +/** + * + */ +package com.liferay.portal.events; + +import java.util.List; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpSession; + +import org.hibernate.criterion.DetachedCriteria; +import org.hibernate.criterion.MatchMode; +import org.hibernate.criterion.Order; +import org.hibernate.criterion.Restrictions; + +import com.liferay.portal.NoSuchLayoutException; +import com.liferay.portal.PortalException; +import com.liferay.portal.SystemException; +import com.liferay.portal.kernel.dao.DynamicQueryInitializer; +import com.liferay.portal.kernel.util.StringPool; +import com.liferay.portal.model.Layout; +import com.liferay.portal.model.LayoutConstants; +import com.liferay.portal.model.impl.LayoutImpl; +import com.liferay.portal.service.LayoutLocalServiceUtil; +import com.liferay.util.dao.hibernate.DynamicQueryInitializerImpl; + +/** + * @author fricke + * + */ +public class ExtensionPointUtil extends + com.liferay.portal.util.ExtensionPointUtil { + /** + * + * @param layout + * The requested layout + * @param request + * The request + * @return the extension target layout for an extension point or the + * original layout, if no extension point is requested or no target + * is known. + */ + public static Layout getExtensionTarget(Layout layout, + HttpServletRequest request, boolean deepHistory) { + if (layout == null) { + return null; + } + + Layout targetLayout = layout; + HttpSession session = request.getSession(false); + + boolean isExtensionPoint = LAYOUT_TYPE_EXTENSION_POINT + .equals(targetLayout.getType()); + // disable deepHistory if the requested layout is an extension point + // (will not come from navigation) + boolean considerDeepHistory = deepHistory && !isExtensionPoint; + while (session != null && (isExtensionPoint || considerDeepHistory)) { + + // Check if an extension point is defined for the top ancestor + String attributeName = getAttributeName(targetLayout.getPlid(), + !isExtensionPoint); + Object targetPlid = session.getAttribute(attributeName); + // if no target is known yet AND it is an extension point AND + // exactly one target is configured that target is used and stored + // as extension target. This automatism is only done for non hidden + // layouts or if deepHistory is wished + if (targetPlid == null && isExtensionPoint + && (deepHistory || !targetLayout.getHidden())) { + List targets = getAllExtensionTargets(targetLayout); + if (targets.size() == 1) { + targetPlid = new Long(((Layout) targets.get(0)).getPlid()); + session.setAttribute(attributeName, targetPlid); + } else { + session.setAttribute(attributeName, Boolean.FALSE); + } + } + + if (targetPlid instanceof Long) { + long plid = ((Long) targetPlid).longValue(); + if (plid != targetLayout.getPlid()) { + try { + targetLayout = LayoutLocalServiceUtil.getLayout(plid); + isExtensionPoint = LAYOUT_TYPE_EXTENSION_POINT + .equals(targetLayout.getType()); + continue; + } catch (NoSuchLayoutException e) { + // Session value is invalid; remove it + session.removeAttribute(attributeName); + } catch (PortalException e) { + throw new RuntimeException(e); + } catch (SystemException e) { + throw new RuntimeException(e); + } + } + } + + break; + } + + return targetLayout; + } + + /** + * @param extLayout + * an extension point layout + * @return a list of layouts that defines the given layout as extension + * point + */ + public static List getAllExtensionTargets(Layout extLayout) { + // Select all top level layouts that use the selLayout as extension + // point + DetachedCriteria criteria = DetachedCriteria.forClass(LayoutImpl.class); + criteria.add(Restrictions.eq("companyId", new Long(extLayout + .getCompanyId()))); + criteria.add(Restrictions.eq("parentLayoutId", Long + .valueOf(LayoutConstants.DEFAULT_PARENT_LAYOUT_ID))); + criteria.add(Restrictions.eq("privateLayout", Boolean.valueOf(extLayout + .isPrivateLayout()))); + criteria.add(Restrictions.ilike("typeSettings", "extension-point=" + + extLayout.getGroup().getName() + StringPool.SLASH + + extLayout.getLayoutId(), MatchMode.ANYWHERE)); + criteria.addOrder(Order.asc("groupId")); + criteria.addOrder(org.hibernate.criterion.Order.asc("name")); + + DynamicQueryInitializer queryInitializer = new DynamicQueryInitializerImpl( + criteria); + List targets; + try { + targets = LayoutLocalServiceUtil.dynamicQuery(queryInitializer); + } catch (SystemException e) { + throw new RuntimeException(e); + } + + return targets; + } + +} Index: portal-impl/src/com/liferay/portal/events/HmServicePreAction.java =================================================================== --- portal-impl/src/com/liferay/portal/events/HmServicePreAction.java (revision 0) +++ portal-impl/src/com/liferay/portal/events/HmServicePreAction.java (revision 0) @@ -0,0 +1,104 @@ +/** + * + */ +package com.liferay.portal.events; + +import java.util.List; + +import javax.servlet.http.HttpServletRequest; + +import com.liferay.portal.PortalException; +import com.liferay.portal.SystemException; +import com.liferay.portal.events.ServicePreAction; +import com.liferay.portal.model.Layout; +import com.liferay.portal.model.LayoutConstants; +import com.liferay.portal.model.User; +import com.liferay.portal.security.permission.PermissionChecker; +import com.liferay.portal.service.LayoutLocalServiceUtil; + +/** + * This class adds support for extensions points to the ServicePreAction class. + * Extension points allows to define specific layout pages in one community that + * are replaced by navigation branches of other communities. + * + * @author Olaf Fricke + * + */ +public class HmServicePreAction extends ServicePreAction { + + /** + * Calculates the viewable layouts. + *
+ * This method is used to perform the extension of communities at runtime. + * It consists of the following steps: + *
+ + |
+ + <% + long selLayoutPlid = selLayout.getPlid(); + String extendValue = GetterUtil.getString(selLayout.getTypeSettingsProperties().getProperty("extension-point", StringPool.BLANK)); + %> + + | +
@@ -420,4 +466,4 @@
}
"); + sm.append(" "); + } - if (selectedLayout) { - if (layoutParentId != LayoutConstants.DEFAULT_PARENT_LAYOUT_ID) { - breadCrumbSM.append(" "); - breadCrumbSM.append(" "); + sm.append(" ");
+ sm.append(curLayout.getName(themeDisplay.getLocale()));
+ sm.append(" ");
+ sm.append(""); } + else { + sm.append(""); + sm.append(curLayout.getName(themeDisplay.getLocale())); + sm.append(""); - breadCrumbSM.append(" ");
- breadCrumbSM.append(selLayout.getName(themeDisplay.getLocale()));
- breadCrumbSM.append(" ");
- breadCrumbSM.append(""); + sm.append(" » "); + } } - else { - breadCrumbSM.append(""); - breadCrumbSM.append(selLayout.getName(themeDisplay.getLocale())); - breadCrumbSM.append(""); - } - - Layout layoutParent = null; - - if (layoutParentId != LayoutConstants.DEFAULT_PARENT_LAYOUT_ID) { - layoutParent = LayoutLocalServiceUtil.getLayout(selLayout.getGroupId(), selLayout.isPrivateLayout(), layoutParentId); - - _buildBreadcrumb(layoutParent, selLayoutParam, portletURL, themeDisplay, false, sm); - - sm.append(" » "); - sm.append(breadCrumbSM.toString()); - } - else { - sm.append(breadCrumbSM.toString()); - } } private String _getBreadcrumbLayoutURL(Layout selLayout, String selLayoutParam, PortletURL portletURL, ThemeDisplay themeDisplay) throws Exception { @@ -86,4 +82,4 @@ return portletURL.toString(); } } -%> \ No newline at end of file +%> Index: portal-web/docroot/html/taglib/ui/navigation/page.jsp =================================================================== --- portal-web/docroot/html/taglib/ui/navigation/page.jsp (revision 16351) +++ portal-web/docroot/html/taglib/ui/navigation/page.jsp (working copy) @@ -30,11 +30,8 @@ Layout rootLayout = null; boolean hidden = false; - List selBranch = new ArrayList(); + List selBranch = com.liferay.portal.events.ExtensionPointUtil.getExtendedAncestors(layout, request); - selBranch.add(layout); - selBranch.addAll(layout.getAncestors()); - if (rootLayoutType.equals("relative")) { if ((rootLayoutLevel >= 0) && (rootLayoutLevel < selBranch.size())) { rootLayout = (Layout) selBranch.get(rootLayoutLevel); @@ -85,7 +82,7 @@ if (!hidden) { StringMaker sm = new StringMaker(); - _buildNavigation(rootLayout, layout, selBranch, themeDisplay, 1, includedLayouts, sm); + _buildNavigation(rootLayout, layout, selBranch, themeDisplay, 1, includedLayouts, sm, request); out.print(sm.toString()); } @@ -95,14 +92,17 @@ <%! -private void _buildNavigation(Layout rootLayout, Layout selLayout, List selBranch, ThemeDisplay themeDisplay, int layoutLevel, String includedLayouts, StringMaker sm) throws Exception { +private void _buildNavigation(Layout rootLayout, Layout selLayout, List selBranch, ThemeDisplay themeDisplay, int layoutLevel, String includedLayouts, StringMaker sm, HttpServletRequest request) throws Exception { List layoutChildren = null; if (rootLayout != null) { + // replace the layout by its extension target if a target is known + rootLayout = com.liferay.portal.events.ExtensionPointUtil.getExtensionTarget(rootLayout, request, false); layoutChildren = rootLayout.getChildren(); } else { - layoutChildren = LayoutLocalServiceUtil.getLayouts(selLayout.getGroupId(), selLayout.isPrivateLayout(), LayoutConstants.DEFAULT_PARENT_LAYOUT_ID); + Layout topLayout = com.liferay.portal.events.ExtensionPointUtil.getExtendedAncestor(selLayout, request); + layoutChildren = LayoutLocalServiceUtil.getLayouts(topLayout.getGroupId(), topLayout.isPrivateLayout(), LayoutConstants.DEFAULT_PARENT_LAYOUT_ID); } if (layoutChildren.size() > 0) { @@ -110,6 +110,8 @@ for (int i = 0; i < layoutChildren.size(); i++) { Layout layoutChild = (Layout)layoutChildren.get(i); + // replace the layout by its extension target if a target is known + layoutChild = com.liferay.portal.events.ExtensionPointUtil.getExtensionTarget(layoutChild, request, false); if (!layoutChild.isHidden() && LayoutPermissionUtil.contains(themeDisplay.getPermissionChecker(), layoutChild, ActionKeys.VIEW)) { String layoutURL = PortalUtil.getLayoutURL(layoutChild, themeDisplay); @@ -131,7 +133,7 @@ className.append("open "); } - if (selLayout.getLayoutId() == layoutChild.getLayoutId()) { + if (selLayout.getPlid() == layoutChild.getPlid()) { className.append("selected "); } @@ -161,7 +163,7 @@ sm.append(""); if (open) { - _buildNavigation(layoutChild, selLayout, selBranch, themeDisplay, layoutLevel + 1, includedLayouts, sm); + _buildNavigation(layoutChild, selLayout, selBranch, themeDisplay, layoutLevel + 1, includedLayouts, sm, request); } sm.append(""); @@ -171,4 +173,4 @@ sm.append(""); } } -%> \ No newline at end of file +%> |